<template>
  <div>
    <h2 class="mb-4">存储配置</h2>
    <a-form :model="form" layout="vertical">
      <a-form-item label="存储类型" name="storageType">
        <a-select v-model:value="form.storageType" placeholder="请选择存储类型">
          <a-select-option value="local">本地存储</a-select-option>
          <a-select-option value="tencent">腾讯云OSS</a-select-option>
          <a-select-option value="aliyun">阿里云OSS</a-select-option>
          <a-select-option value="minio">MinioOSS</a-select-option>
        </a-select>
      </a-form-item>

      <template v-if="form.storageType === 'tencent' || form.storageType === 'aliyun' || form.storageType === 'minio'">
        <a-form-item label="accessKey" name="accessKey">
          <a-input v-model:value="form.accessKey" placeholder="请输入accessKey" />
        </a-form-item>
        <a-form-item label="secretKey" name="secretKey">
          <a-input-password v-model:value="form.secretKey" placeholder="请输入secretKey" />
        </a-form-item>
        <a-form-item label="bucket" name="bucket">
          <a-input v-model:value="form.bucket" placeholder="请输入bucket" />
        </a-form-item>
        <a-form-item label="endpoint" name="region">
          <a-input v-model:value="form.region" placeholder="请输入endpoint" />
        </a-form-item>
      </template>

      <a-form-item>
        <a-space>
          <a-button type="primary" @click="handleSave">保存配置</a-button>
          <a-button @click="handleTest">测试连接</a-button>
        </a-space>
      </a-form-item>
    </a-form>

    <!-- 测试区域 -->
    <div class="test-area">
      <a-collapse v-model:activeKey="activeKey" :bordered="false">
        <a-collapse-panel key="1" :show-arrow="false">
          <template #header>
            <div class="collapse-header">
              <h2 class="mb-0">存储测试</h2>
              <a-button type="link" @click.stop="toggleTest">
                {{ isExpanded ? '收起' : '展开' }}
                <down-outlined :class="{ 'rotate-icon': isExpanded }" />
              </a-button>
            </div>
          </template>

          <!-- 文件上传区域 -->
          <a-upload
            :file-list="fileList"
            :before-upload="beforeUpload"
            :customRequest="handleUpload"
            :show-upload-list="false"
            :multiple="false"
          >
            <a-button type="primary">
              <upload-outlined />
              选择文件
            </a-button>
          </a-upload>

          <!-- 文件列表 -->
          <div class="file-list mt-4">
            <a-table
              :columns="columns"
              :data-source="fileList"
              :pagination="false"
              size="small"
            >
              <template #bodyCell="{ column, record }">
                <template v-if="column.key === 'action'">
                  <a-space>
                    <a-button type="link" size="small" @click="handlePreview(record)">
                      下载
                    </a-button>
                    <a-button type="link" size="small" danger @click="handleDelete(record)">
                      删除
                    </a-button>
                  </a-space>
                </template>
                <template v-if="column.key === 'status'">
                  <a-tag :color="record.status === 'success' ? 'success' : 'error'">
                    {{ record.status === 'success' ? '上传成功' : '上传失败' }}
                  </a-tag>
                </template>
              </template>
            </a-table>
          </div>
        </a-collapse-panel>
      </a-collapse>
    </div>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { UploadOutlined, DownOutlined } from '@ant-design/icons-vue'
import type { UploadProps } from 'ant-design-vue'
import type { UploadFile } from 'ant-design-vue/es/upload/interface'
import { anyHttpClient } from '@/network'

const form = reactive({
  storageType: '',
  accessKey: '',
  secretKey: '',
  bucket: '',
  region: '',
})

// 文件列表
interface FileItem {
  uid: number
  name: string
  status: 'success' | 'error'
  size: number
  url: string
  path: string
  type: string
  createTime: string
}

const fileList = ref<FileItem[]>([])

// 表格列定义
const columns = [
  {
    title: '文件名',
    dataIndex: 'name',
    key: 'name',
  },
  {
    title: '大小',
    dataIndex: 'size',
    key: 'size',
    customRender: ({ text }: { text: number }) => {
      const size = text / 1024
      return size > 1024 ? `${(size / 1024).toFixed(2)} MB` : `${size.toFixed(2)} KB`
    }
  },
  {
    title: '类型',
    dataIndex: 'type',
    key: 'type',
  },
  {
    title: '上传时间',
    dataIndex: 'createTime',
    key: 'createTime',
  },
  {
    title: '状态',
    dataIndex: 'status',
    key: 'status',
  },
  {
    title: '操作',
    key: 'action',
  },
]

// 上传前检查
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
  const isLt10M = file.size / 1024 / 1024 < 10
  if (!isLt10M) {
    message.error('文件大小不能超过10MB!')
    return false
  }
  return true
}

// 处理文件上传
const handleUpload = async ({ file, onSuccess, onError }: any) => {
  let tempFile: FileItem | null = null;
  try {
    // 创建临时文件对象，显示上传中状态
    tempFile = {
      uid: Date.now(),
      name: (file as UploadFile).name || '未命名文件',
      status: 'success', // 初始状态设为成功,后续根据上传结果更新
      size: (file as UploadFile).size || 0,
      url: '',
      path: '',
      type: (file as File).type || '',
      createTime: new Date().toLocaleString() // 确保初始时间格式正确
    }

    // 先添加到列表中显示上传中状态
    fileList.value = [...fileList.value, tempFile]

    // 配置存储
    const config = {
      type: form.storageType,
      accessKeyId: form.accessKey,
      accessKeySecret: form.secretKey,
      bucket: form.bucket,
      endpoint: form.region,
      region: form.region
    }
    await anyHttpClient.post('/api/oss/switch', config)

    // 上传文件
    const formData = new FormData()
    formData.append('file', file as File)
    formData.append('isPublic', 'true')

    const response = await anyHttpClient.post('/api/oss/upload', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })

    // 检查响应数据
    if (!response || !response.data) {
      throw new Error('上传响应数据格式错误')
    }

    // 使用后端返回的数据更新临时文件
    const responseData = response.data

    // 更新文件列表中的临时文件为成功状态
    fileList.value = fileList.value.map(item => {
      if (item.uid === tempFile!.uid) {
        return {
          ...item,
          status: 'success',
          url: responseData.url || '',
          path: responseData.path || '',
          name: responseData.name || item.name,
          size: responseData.size || item.size,
          // 如果后端返回了创建时间，则使用后端的时间，否则保留前端生成的时间
          createTime: responseData.createTime || item.createTime
        }
      }
      return item
    })

    if (tempFile !== null) {
      console.log('上传成功，文件信息：', fileList.value.find(item => item.uid === tempFile.uid))
      message.success(`${tempFile.name} 上传成功`)
    }
    onSuccess?.('ok')
  } catch (error: any) {
    console.error('上传失败:', error)

    // 如果上传失败，将状态更新为失败
    if (tempFile !== null) {
      fileList.value = fileList.value.map(item => {
        if (item.uid === tempFile!.uid) {
          return {
            ...item,
            status: 'error'
          }
        }
        return item
      })
    }

    message.error(`上传失败: ${error.message || '未知错误'}`)
    onError?.(error)
  }
}

// 预览文件
const handlePreview = (file: FileItem) => {
  if (file.url) {
    window.open(file.url, '_blank')
  } else {
    message.warning('文件URL不存在')
  }
}

// 删除文件
const handleDelete = async (file: FileItem) => {
  try {
    if (!file.path) {
      message.error('文件路径不存在')
      return
    }

    // 将路径中的斜杠替换为下划线，避免URL编码问题
    const encodedPath = file.path.replace(/\//g, '_')

    const response = await anyHttpClient.post(`/api/oss/delete/${encodedPath}`)

    if (response.data && response.data.success) {
      const index = fileList.value.findIndex(item => item.uid === file.uid)
      if (index > -1) {
        fileList.value.splice(index, 1)
      }
      message.success('文件删除成功')
    } else {
      message.error((response.data && response.data.message) || '文件删除失败')
    }
  } catch (error: any) {
    message.error('文件删除失败：' + (error.message || '未知错误'))
  }
}

const handleSave = async () => {
  try {
    const config = {
      type: form.storageType,
      accessKeyId: form.accessKey,
      accessKeySecret: form.secretKey,
      bucket: form.bucket,
      endpoint: form.region,
      region: form.region
    }
    await anyHttpClient.post('/api/oss/switch', config)
    message.success('存储配置保存成功')

    // 保存配置信息到本地存储
    localStorage.setItem('ossConfig', JSON.stringify({
      storageType: form.storageType,
      accessKey: form.accessKey,
      secretKey: form.secretKey,
      bucket: form.bucket,
      region: form.region
    }))
  } catch (error: any) {
    message.error('存储配置保存失败：' + (error.message || '未知错误'))
  }
}

// 在组件挂载时加载保存的配置
onMounted(() => {
  const savedConfig = localStorage.getItem('ossConfig')
  if (savedConfig) {
    const config = JSON.parse(savedConfig)
    form.storageType = config.storageType
    form.accessKey = config.accessKey
    form.secretKey = config.secretKey
    form.bucket = config.bucket
    form.region = config.region
  }
})

const handleTest = () => {
  message.info('测试连接功能暂未实现')
}

// 折叠面板状态
const activeKey = ref<string[]>([])
const isExpanded = ref(false)

// 切换折叠状态
const toggleTest = () => {
  isExpanded.value = !isExpanded.value
  activeKey.value = isExpanded.value ? ['1'] : []
}
</script>

<style scoped>
.mb-4 {
  margin-bottom: 16px;
}
.mt-4 {
  margin-top: 16px;
}
.test-area {
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid #f0f0f0;
}
.file-list {
  margin-top: 16px;
}
.collapse-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}
.collapse-header h2 {
  margin: 0;
}
.rotate-icon {
  transform: rotate(180deg);
  transition: transform 0.3s;
}
:deep(.ant-collapse-header) {
  padding: 0 !important;
}
:deep(.ant-collapse-content) {
  border-top: none !important;
}
:deep(.ant-collapse-item) {
  border: none !important;
}
</style>

